1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package java.lang;
27
28 import java.io.DataInputStream;
29 import java.io.InputStream;
30 import java.lang.ref.SoftReference;
31 import java.util.Arrays;
32 import java.util.zip.InflaterInputStream;
33 import java.security.AccessController;
34 import java.security.PrivilegedAction;
35
36 class CharacterName {
37
38 private static SoftReference<byte[]> refStrPool;
39 private static int[][] lookup;
40
41 private static synchronized byte[] initNamePool() {
42 byte[] strPool = null;
43 if (refStrPool != null && (strPool = refStrPool.get()) != null)
44 return strPool;
45 DataInputStream dis = null;
46 try {
47 dis = new DataInputStream(new InflaterInputStream(
48 AccessController.doPrivileged(new PrivilegedAction<InputStream>()
49 {
50 public InputStream run() {
51 return getClass().getResourceAsStream("uniName.dat");
52 }
53 })));
54
55 lookup = new int[(Character.MAX_CODE_POINT + 1) >> 8][];
56 int total = dis.readInt();
57 int cpEnd = dis.readInt();
58 byte ba[] = new byte[cpEnd];
59 dis.readFully(ba);
60
61 int nameOff = 0;
62 int cpOff = 0;
63 int cp = 0;
64 do {
65 int len = ba[cpOff++] & 0xff;
66 if (len == 0) {
67 len = ba[cpOff++] & 0xff;
68
69 cp = ((ba[cpOff++] & 0xff) << 16) |
70 ((ba[cpOff++] & 0xff) << 8) |
71 ((ba[cpOff++] & 0xff));
72 } else {
73 cp++;
74 }
75 int hi = cp >> 8;
76 if (lookup[hi] == null) {
77 lookup[hi] = new int[0x100];
78 }
79 lookup[hi][cp&0xff] = (nameOff << 8) | len;
80 nameOff += len;
81 } while (cpOff < cpEnd);
82 strPool = new byte[total - cpEnd];
83 dis.readFully(strPool);
84 refStrPool = new SoftReference<>(strPool);
85 } catch (Exception x) {
86 throw new InternalError(x.getMessage());
87 } finally {
88 try {
89 if (dis != null)
90 dis.close();
91 } catch (Exception xx) {}
92 }
93 return strPool;
94 }
95
96 public static String get(int cp) {
97 byte[] strPool = null;
98 if (refStrPool == null || (strPool = refStrPool.get()) == null)
99 strPool = initNamePool();
100 int off = 0;
101 if (lookup[cp>>8] == null ||
102 (off = lookup[cp>>8][cp&0xff]) == 0)
103 return null;
104 return new String(strPool, 0, off >>> 8, off & 0xff);
105 }
106 }